#include "agentglwidget.h"
#include <QTimer>

AgentGLWidget::AgentGLWidget(QString resDir, QWidget *parent):
    QOpenGLWidget (parent)
{
    QSurfaceFormat format;
    format.setSamples(16);
    format.setSwapInterval(1);
    setFormat(format);

    this->resourceDir = resDir;
    QTimer *timer = new QTimer(this);
    connect(timer,SIGNAL(timeout()),this,SLOT(update()));
    timer->start(1000.0/FPS);
}

AgentGLWidget::~AgentGLWidget()
{
    delete mmdScene;
    delete model;
}

void AgentGLWidget::ChangeMonth(bool state)
{
    model->month_enable = state;
    SetMotions(state?"talk0":"idle0",true,true);
}

void AgentGLWidget::InitMotions()
{
    AddMotions("talk0",resourceDir+"motion/mei_guide_happy.vmd");
    AddMotions("talk1",resourceDir+"motion/mei_self_introduction.vmd");
    AddMotions("idle0",resourceDir+"motion/mei_idle_boredom.vmd");
    AddMotions("idle1",resourceDir+"motion/mei_idle_sleep.vmd");
    AddMotions("idle2",resourceDir+"motion/mei_idle_think.vmd");
    AddMotions("idle3",resourceDir+"motion/mei_idle_touch_clothes.vmd");
    AddMotions("idle4",resourceDir+"motion/mei_idle_yawn.vmd");
    AddMotions("show",resourceDir+"motion/mei_panel_on.vmd");
}

void AgentGLWidget::AutoPLayIdle()
{
    if((sum_idle_time += model->elapsed) > 5.0f && cur_anim.indexOf("idle") != -1){
        QString anim_name = "idle" + QString::number(rand() % 5);
        SetMotions(anim_name,false,true);
        sum_idle_time -= 5.0f;
    }
}

void AgentGLWidget::AddMotions(QString Key, QString filePath)
{
    auto &tmp = motions[Key] = saba::VMDFile();
    saba::ReadVMDFile(&tmp,filePath.toLatin1());
}

void AgentGLWidget::SetMotions(QString Key, bool Loop, bool Clear)
{
    model->frames = 0;
    model->passtime = 0;
    cur_anim = Key;
    if(Clear){
        delete model->anim;
        model->anim = new saba::VMDAnimation;
        model->anim->Create(model->model);
    }
    model->anim->Add(motions[Key]);
    model->anim->SyncPhysics(0.0f);
    model->Anim_Loop = Loop;
}

void AgentGLWidget::initializeGL()
{
    initializeOpenGLFunctions();
    //glEnable(GL_MULTISAMPLE);
    glClearColor(1.0, 1.0, 1.0, 1.0);

    InitMotions();
    mmdScene = new MMDScene(resourceDir+"shader/mmd.vert",resourceDir+"shader/mmd.frag");
    model = new Model(resourceDir+"model/rem/rem.pmx",resourceDir+"mmd",mmdScene);
    SetMotions("idle0",true,true);
}

void AgentGLWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    AutoPLayIdle();
    model->Update();
    model->Draw();
}

void AgentGLWidget::resizeGL(int width, int height)
{
    glViewport(0,0,width,height);
    mmdScene->m_viewMat = glm::lookAt(glm::vec3(0, 10, 50), glm::vec3(0, 10, 0), glm::vec3(0, 1, 0));
    mmdScene->m_projMat = glm::perspectiveFovRH(glm::radians(30.0f), float(width), float(height), 1.0f, 10000.0f);
    repaint();
}
